home *** CD-ROM | disk | FTP | other *** search
/ Java Programmer's Toolkit / Java Programmer's Toolkit.iso / solaris2 / jdk / src / java / net / inetaddr.jav < prev    next >
Encoding:
Text File  |  1995-10-30  |  8.6 KB  |  280 lines

  1. /*
  2.  * @(#)InetAddress.java    1.18 95/10/26 Jonathan Payne
  3.  *
  4.  * Copyright (c) 1994 Sun Microsystems, Inc. All Rights Reserved.
  5.  *
  6.  * Permission to use, copy, modify, and distribute this software
  7.  * and its documentation for NON-COMMERCIAL purposes and without
  8.  * fee is hereby granted provided that this copyright notice
  9.  * appears in all copies. Please refer to the file "copyright.html"
  10.  * for further important copyright and licensing information.
  11.  *
  12.  * SUN MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF
  13.  * THE SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
  14.  * TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
  15.  * PARTICULAR PURPOSE, OR NON-INFRINGEMENT. SUN SHALL NOT BE LIABLE FOR
  16.  * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
  17.  * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES.
  18.  */
  19.  
  20. package java.net;
  21.  
  22. import java.util.Hashtable;
  23.  
  24. /**
  25.  * A class that represents internet addresses.
  26.  *
  27.  * @version     1.18, 10/26/95
  28.  * @author     Jonathan Payne
  29.  * @author     Arthur van Hoff
  30.  * @author     Chris Warth
  31.  */
  32. public final 
  33. class InetAddress {
  34.     private static boolean inCheck = false;
  35.  
  36.     String hostName;
  37.     int address;    // Currently we only deal effectively with 32-bit addresses. 
  38.             // However this field can be expanded to be a byte array 
  39.             // or a 64-bit quantity without too much effort.
  40.     int family;
  41.  
  42.     /** 
  43.      * Constructor for the Socket.accept() method.
  44.      * This creates an empty InetAddress, which is filled in by
  45.      * the accept() method.  This InetAddress, however, is not
  46.      * put in the address cache, since it is not created by name.
  47.      */
  48.     InetAddress() {}
  49.  
  50.     /**
  51.      * Creates an InetAddress with the specified host name and IP address.
  52.      * @param hostName the specified host name
  53.      * @param addr the specified IP address.  The address is expected in 
  54.      *          network byte order.
  55.      * @exception UnknownHostException If the address is unknown.
  56.      */
  57.     InetAddress(String hostName, byte addr[]) {
  58.     this.hostName = hostName;
  59.     this.family = getInetFamily();
  60.     /*
  61.      * We must be careful here to maintain the network byte
  62.      * order of the address.  As it comes in, the most
  63.      * significant byte of the address is in addr[0].  It
  64.      * actually doesn't matter what order they end up in the
  65.      * array, as long as it is documented and consistent.
  66.      */
  67.     address  = addr[3] & 0xFF;
  68.     address |= ((addr[2] << 8) & 0xFF00);
  69.     address |= ((addr[1] << 16) & 0xFF0000);
  70.     address |= ((addr[0] << 24) & 0xFF000000);
  71.     }
  72.  
  73.     /**
  74.      * Gets the hostname for this address; also the key in the above
  75.      * hash table.
  76.      * If the host is equal to null, then this address refers to any
  77.      * of the local machine's available network addresses.
  78.      */
  79.     public String getHostName() {
  80.     if (hostName == null) {
  81.         try {
  82.         hostName = getHostByAddr(address);
  83.         } catch (UnknownHostException e) {
  84.         hostName = 
  85.            ((address >>> 24) & 0xFF) + "." +
  86.            ((address >>> 16) & 0xFF) + "." +
  87.            ((address >>>  8) & 0xFF) + "." +
  88.            ((address >>>  0) & 0xFF);
  89.         }
  90.     }
  91.  
  92.     return hostName;
  93.     }
  94.  
  95.     /**
  96.      * Returns the raw IP address in network byte order.  The
  97.      * highest order byte position is in addr[0].  An array of bytes
  98.      * is returned so we are prepared for 64-bit IP addresses.
  99.      * @return raw IP address in network byte order.
  100.      */
  101.     public byte[] getAddress() {    
  102.     byte[] addr = new byte[4];
  103.  
  104.     addr[0] = (byte) ((address >>> 24) & 0xFF);
  105.     addr[1] = (byte) ((address >>> 16) & 0xFF);
  106.     addr[2] = (byte) ((address >>> 8) & 0xFF);
  107.     addr[3] = (byte) (address & 0xFF);
  108.     return addr;
  109.     }
  110.  
  111.     /**
  112.      * Returns a hashcode for this InetAddress.
  113.      */
  114.     public int hashCode() {
  115.     return address;
  116.     }
  117.  
  118.     /**
  119.      * Compares this object against the specified object.
  120.      * @param obj the object to compare with
  121.      * @return true if the objects are the same; false otherwise.
  122.      */
  123.     public boolean equals(Object obj) {
  124.     return (obj != null) && (obj instanceof InetAddress) &&
  125.         (((InetAddress)obj).address == address);
  126.     }
  127.  
  128.     /**
  129.      * Converts the InetAddress to a String.
  130.      */
  131.     public String toString() {
  132.     return ((hostName != null) ? hostName + "/" : "") +
  133.            ((address >>> 24) & 0xFF) + "." +
  134.            ((address >>> 16) & 0xFF) + "." +
  135.            ((address >>>  8) & 0xFF) + "." +
  136.            ((address >>>  0) & 0xFF);
  137.     }
  138.  
  139.     /* Cached addresses - our own litle nis, not! */
  140.     static Hashtable        addressCache = new Hashtable();
  141.     static InetAddress        unknownAddress;
  142.     static InetAddress        anyLocalAddress;
  143.     static InetAddress      localHost;
  144.  
  145.     static {
  146.     unknownAddress = new InetAddress();
  147.     anyLocalAddress = new InetAddress();
  148.     makeAnyLocalAddress(anyLocalAddress);
  149.     try {
  150.         localHost = getByName(getLocalHostName());
  151.     } catch (Exception ex) {
  152.         localHost = unknownAddress;
  153.     }
  154.     }
  155.  
  156.     /**
  157.      * Returns a network address for the indicated host.  A host name
  158.      * of null refers to default address for the local machine.  A local
  159.      * cache is used to speed access to addresses.  If a all
  160.      * addresses for host are needed, use the getAllByName() method.
  161.      * @param host the specified host
  162.      * @exception UnknownHostException If the address is unknown.
  163.      */
  164.     public static synchronized InetAddress getByName(String host)
  165.     throws UnknownHostException
  166.     {
  167.     if (host == null || host.length() == 0) {
  168.         return localHost;
  169.     }
  170.  
  171.     /* make sure the connection to the host is allowed, before we
  172.        create the InetAddress */
  173.     SecurityManager security = System.getSecurityManager();
  174.     if (security != null && !security.getInCheck()) {
  175.         security.checkConnect(host, -1);
  176.     }
  177.  
  178.     /* Cache.get can return: null, unknownAddress, InetAddress,
  179.     or InetAddress[] */
  180.     Object obj = addressCache.get(host);
  181.     if (obj == null) {
  182.         try {
  183.         /*
  184.          * Do not put the call to lookup() inside the
  185.          * constructor.  if you do you will still be
  186.          * allocating space when the lookup fails.
  187.          */
  188.         byte addr[] = lookupHostAddr(host);
  189.         obj = new InetAddress(host, addr);
  190.         } catch (UnknownHostException e) {
  191.         obj  = unknownAddress;
  192.         }
  193.         addressCache.put(host, obj);
  194.     } else if (obj instanceof InetAddress[]) {
  195.         InetAddress addr_array[] = (InetAddress []) obj;
  196.         obj = addr_array[0];
  197.     }
  198.         
  199.     if (obj == unknownAddress) {
  200.         /*
  201.          * We currently cache the fact that a host is unknown.
  202.          */
  203.         throw new UnknownHostException(host);
  204.     }
  205.     return (InetAddress) obj;
  206.     }
  207.  
  208.     /** 
  209.      * Given a hostname, return an array of all the corresponding InetAddresses.  
  210.      */
  211.     public static synchronized InetAddress getAllByName(String host)[]
  212.     throws UnknownHostException
  213.     {
  214.     if (host == null) {
  215.         throw new UnknownHostException(host);
  216.     }
  217.  
  218.     /* make sure the connection to the host is allowed, before we
  219.        create the InetAddress */
  220.     SecurityManager security = System.getSecurityManager();
  221.     if (security != null && !security.getInCheck()) {
  222.         security.checkConnect(host, -1);
  223.     }
  224.  
  225.        /* Cache.get can return: null, unknownAddress, InetAddress,
  226.     or InetAddress[] */
  227.     Object obj = addressCache.get(host);
  228.     
  229.     /* If no entry in cache, or entry in the cache points to a single
  230.        InetAddress (not an array), then do the host lookup */
  231.     if (obj == null ||
  232.         ((obj!=unknownAddress) && (obj instanceof InetAddress)) ) {
  233.         try {
  234.         /*
  235.          * Do not put the call to lookup() inside the
  236.          * constructor.  if you do you will still be
  237.          * allocating space when the lookup fails.
  238.          */
  239.         byte[][] byte_array = lookupAllHostAddr(host);
  240.         InetAddress[] addr_array = new InetAddress[byte_array.length];
  241.         for (int i = 0; i < byte_array.length; i++) {
  242.             byte addr[] = byte_array[i];
  243.             addr_array[i] = new InetAddress(host, addr);
  244.         }
  245.         obj = addr_array;
  246.         } catch (UnknownHostException e) {
  247.         obj  = unknownAddress;
  248.         }
  249.         addressCache.put(host, obj);
  250.     } 
  251.         
  252.     if (obj == unknownAddress) {
  253.         /*
  254.          * We currently cache the fact that a host is unknown.
  255.          */
  256.         throw new UnknownHostException(host);
  257.     }
  258.     return (InetAddress []) obj;
  259.     }
  260.  
  261.     /**
  262.      * Returns the local host.
  263.      */
  264.     public static InetAddress getLocalHost() throws UnknownHostException {
  265.         if (localHost.equals(unknownAddress)) {
  266.         throw new UnknownHostException();
  267.     }
  268.     return localHost;
  269.     }
  270.  
  271.     private static native String getLocalHostName() throws UnknownHostException;
  272.     private static native void makeAnyLocalAddress(InetAddress addr);
  273.     private static native byte[] lookupHostAddr(String hostname) throws UnknownHostException;
  274.     private static native byte[][]
  275.         lookupAllHostAddr(String hostname) throws UnknownHostException;
  276.     private static native String getHostByAddr(int addr) throws UnknownHostException;
  277.     private static native int getInetFamily();
  278. }
  279.  
  280.